<template>
  <div class="app-container">
    <el-card>
      <template #header>
        <div class="card-header">
          <span>品牌管理</span>
          <el-button type="primary" @click="handleAdd">新增</el-button>
        </div>
      </template>
      <!-- 搜索区域 -->
      <el-form :model="searchForm" label-width="80px" class="search-form">
        <el-row :gutter="20">
          <el-col :span="6">
            <el-form-item label="品牌名称">
              <el-input v-model="searchForm.name" placeholder="请输入角色名称" />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="状态">
              <el-select v-model="searchForm.showStatus" placeholder="请选择状态" clearable>
                <el-option label="启用" value="1" />
                <el-option label="禁用" value="0" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-button type="primary" @click="handleSearch">搜索</el-button>
            <el-button @click="handleReset">重置</el-button>
          </el-col>
        </el-row>
      </el-form>
      <el-table v-loading="loading" :data="tableData" style="width: 100%" border>
        <el-table-column prop="name" label="品牌名称" width="220" align="center" />
        <el-table-column prop="logo" label="品牌logo" width="180" align="center">
          <template #default="{ row }">
            <div style="display: flex; justify-content: center; align-items: center">
              <img
                :src="row.logo"
                alt="品牌LOGO"
                style="width: 80px; height: 80px; border-radius: 50%"
              />
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="description" label="介绍" align="center" width="180" />
        <el-table-column prop="firstLetter" label="检索首字母" align="center" width="180" />
        <el-table-column label="操作" align="center">
          <template #default="scope">
            <el-button size="small" type="success" @click="handleRelation(scope.row.brandId)"
              >关联分类</el-button
            >

            <el-button size="small" type="warning" @click="handleEdit(scope.row.brandId)"
              >编辑</el-button
            >
            <el-button size="small" type="danger" @click="handleDelete(scope.row.brandId)">
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        v-model:current-page="pageNo"
        v-model:page-size="pageSize"
        :page-sizes="[10, 20, 50, 100]"
        :size="size"
        :background="background"
        layout="total, sizes, prev, pager, next, jumper"
        :total="totalCount"
        style="margin-top: 10px"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
      <!-- 对话框组件 -->
      <el-dialog
        v-model="dialogVisible"
        :title="titleMsg"
        width="500"
        :close-on-click-modal="false"
      >
        <el-form
          ref="ruleFormRef"
          :model="brand"
          label-width="auto"
          style="max-width: 600px"
          :rules="rules"
        >
          <el-form-item label="品牌名称" prop="name">
            <el-input v-model="brand.name" placeholder="请输入分类名称"></el-input>
          </el-form-item>
          <el-form-item label="品牌logo" prop="logo">
            <!--新增：上传图片 -->
            <!--action是自动上传的地址，这个项目不需要 我们需要手动上传  -->
            <!-- :show-file-list="false" 不展示列表 -->
            <!-- :before-upload="beforeAvatarUpload" 检查上传前的函数 -->
            <el-upload
              class="avatar-uploader"
              :action="actionUrl"
              :show-file-list="false"
              :on-success="handleAvatarSuccess"
              :before-upload="beforeAvatarUpload"
            >
              <img v-if="brand.logo" :src="brand.logo" class="avatar" style="width: 200px" />
              <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
            </el-upload>
          </el-form-item>
          <el-form-item label="品牌介绍" prop="description">
            <el-input v-model="brand.description"></el-input>
          </el-form-item>
          <el-form-item label="检索首字母" prop="firstLetter">
            <el-input v-model="brand.firstLetter"></el-input>
          </el-form-item>
        </el-form>
        <template #footer>
          <div class="dialog-footer">
            <el-button @click="dialogVisible = false">关闭</el-button>
            <el-button type="primary" @click="submitData"> 确定 </el-button>
          </div>
        </template>
      </el-dialog>

      <!-- 关联分类对话框组件 -->
      <el-dialog
        v-model="relationDialogVisible"
        title="关联分类"
        width="650"
        :close-on-click-modal="false"
      >
        <el-row style="margin-bottom: 10px">
          <el-col :span="24">
            <el-button type="primary" size="small" @click="cascaderSelect">新增关联分类</el-button>
          </el-col>
        </el-row>

        <el-row>
          <!-- 树形多选区域 -->
          <el-row style="margin-bottom: 10px">
            <el-col>
              <el-cascader
                v-if="showCascaderSelect"
                v-model="catIds"
                :options="options"
                :props="cascaderProps"
                clearable
                filterable
              />
            </el-col>
          </el-row>
          <el-col>
            <!-- 只有在展开穿梭框时，才显示 确定/取消 按钮 -->
            <template v-if="showCascaderSelect">
              <el-button size="small" @click="cancelTreeSelect">取 消</el-button>
              <el-button size="small" type="primary" @click="confirmTreeSelect">确 定</el-button>
            </template>
          </el-col>
        </el-row>

        <el-table key="id" :data="relationTableData" border style="width: 100%; margin-top: 20px">
          <el-table-column prop="brandName" label="品牌名称" width="180" align="center" />
          <el-table-column prop="catName" label="分类名称" width="180" align="center" />
          <el-table-column label="操作" align="center">
            <template #default="scope">
              <el-button size="small" type="danger" @click="deleteRelation(scope.row.id)">
                移除
              </el-button>
            </template>
          </el-table-column>
        </el-table>
        <el-pagination
          v-model:current-page="relationPageNo"
          v-model:page-size="relationPageSize"
          :page-sizes="[10, 20, 50, 100]"
          :size="size"
          :background="background"
          layout="total, sizes, prev, pager, next, jumper"
          :total="relationTotalCount"
          style="margin-top: 10px"
          @size-change="handleRelationSizeChange"
          @current-change="handleRelationCurrentChange"
        />
      </el-dialog>
    </el-card>
  </div>
</template>
<script setup>
import { categoryList } from '@/api/category'
import { ElMessage, ElMessageBox } from 'element-plus'
import { onMounted, ref, reactive } from 'vue'
import { getBrandList, deleteBrandId, getBrandById, updateBrand, insertBrand } from '@/api/brand'
import { removeRelation, relationList, batchSaveRelation } from '@/api/categoryBrandRelation'
const actionUrl = `${import.meta.env.VITE_APP_BASE_API}/third-party-api/file/upload`
//列表数据
const tableData = ref([])
//加载状态
const loading = ref(false)
// 分页器当前的页码数
const pageNo = ref(1)
// 分页器每页显示多少条数据
const pageSize = ref(10)
// 总条数
const totalCount = ref(0)
//分页器大小
const size = ref('default')
// 分页器背景颜色，是/否
const background = ref(true)
// 对话框组件
const dialogVisible = ref(false)
// 对话框标题
const titleMsg = ref('')
// 表单数据
const brand = ref({
  brandId: 0,
  name: '',
  logo: '',
  description: '',
  firstLetter: '',
  showStatus: 0,
  sort: 0
})
//对话框类型:作用用来提交数据时候，区分是修改还是添加
const dialogType = ref('')
/**
 * 搜索
 */
const searchForm = ref({
  name: '',
  showStatus: ''
})
const ruleFormRef = ref(null)
/**
 * 表单验证规则
 */
const rules = reactive({
  name: [{ required: true, message: '请输入品牌名称', trigger: 'blur' }],
  logo: [{ required: true, message: '请上传品牌logo', trigger: 'blur' }],
  description: [{ required: true, message: '请输入品牌介绍', trigger: 'blur' }],
  firstLetter: [
    { required: true, message: '请输入品牌首字母', trigger: 'blur' },
    {
      pattern: /^[A-Z]$/,
      message: '首字母必须为一个大写字母（A-Z），且只能是一位',
      trigger: 'blur'
    }
  ]
})
/**
 * 每页显示的条数发生改变
 */
const handleSizeChange = () => {
  getList()
}
const handleCurrentChange = () => {
  getList()
}
/**
 * 表格数据
 */
onMounted(() => {
  // 获取列表数据
  getList()
})
/**
 * 获取列表数据
 */
const getList = async () => {
  loading.value = true
  const { records, total } = await getBrandList(pageNo.value, pageSize.value, searchForm.value)
  tableData.value = records
  totalCount.value = total
  loading.value = false
}
const submitData = async () => {
  if (!ruleFormRef.value) return
  try {
    // 如果校验失败，这里会 throw
    await ruleFormRef.value.validate()
    // 校验通过
    // … 发接口、关闭弹窗之类的
    console.log('校验通过，开始提交')

    if (dialogType.value == 'add') {
      addBrand()
    } else {
      editBrand()
    }
  } catch (err) {
    // 校验不通过或其它错误都会走到这
    console.warn('校验失败：', err)
    ElMessage.error('请检查表单必填项或格式')
  }
}
/**
 * 新增
 */
const handleAdd = async () => {
  dialogType.value = 'add'
  dialogVisible.value = true
  titleMsg.value = '新增品牌'
  brand.value = {}
}

/**
 * 编辑
 */

const handleEdit = async brandId => {
  brand.value = await getBrandById(brandId)
  dialogType.value = 'edit'
  dialogVisible.value = true
  titleMsg.value = '编辑品牌'
}

/**
 * 添加

 */
const addBrand = async () => {
  await insertBrand(brand.value)
  getList()
  dialogVisible.value = false
  ElMessage({
    type: 'success',
    message: '添加成功'
  })
}
/**
 * 修改
 */
const editBrand = async () => {
  await updateBrand(brand.value)
  getList()
  dialogVisible.value = false
  ElMessage({
    type: 'success',
    message: '修改成功'
  })
}
/**
 * 删除
 */

const handleDelete = brandId => {
  ElMessageBox.confirm('你确定要删除吗?', 'Warning', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  })
    .then(async () => {
      //发送删除请求
      await deleteBrandId(brandId)
      //刷新数据
      getList()
      //提示信息
      ElMessage({
        type: 'success',
        message: '删除成功'
      })
    })
    .catch(() => {
      ElMessage({
        type: 'info',
        message: '取消删除'
      })
    })
}
/**
 * 搜索
 */
const handleSearch = () => {
  getList()
}
/**
 * 重置
 */
const handleReset = () => {
  searchForm.value = {}
  getList()
}
/**
 * 上传之前的文件校验
 * @param file
 */
const beforeAvatarUpload = file => {
  console.log('beforeAvatarUpload方法执行,开始校验文件格式和大小')

  // 支持的图片格式
  const isSupportedFormat = ['image/jpeg', 'image/png', 'image/webp'].includes(
    file.type.toLowerCase()
  )
  // 图片大小限制为10MB
  const isLt10M = file.size / 1024 / 1024 < 10

  if (!isSupportedFormat) {
    ElMessage.error('上传头像图片只能是 JPG, JPEG, PNG 或 WEBP 格式!')
    return false
  }
  if (!isLt10M) {
    ElMessage.error('上传头像图片大小不能超过 10MB!')
    return false
  }

  return isSupportedFormat && isLt10M
}
/**
 * 上传成功之后的处理
 * @param response
 * @param uploadFile
 */
const handleAvatarSuccess = (response, uploadFile) => {
  console.log(uploadFile)
  //收集上传完成之后服务器返回的地址
  brand.value.logo = response.data
  console.log(brand.value.logo)
}
// 分页器当前的页码数
const relationPageNo = ref(1)
// 分页器每页显示多少条数据
const relationPageSize = ref(10)
// 总条数
const relationTotalCount = ref(0)
// 对话框组件
const relationDialogVisible = ref(false)
// 是否显示嵌入式穿梭框
const showCascaderSelect = ref(false)
//级联选择器属性设置
const cascaderProps = {
  multiple: true, //是否可以多选，false:单选，true:多选
  checkStrictly: false, // false不允许选择任意级别,只能选择最后一级
  value: 'catId',
  label: 'name',
  children: 'children',
  emitPath: false //在选中节点改变时，是否返回由该节点所在的各级菜单的值所组成的数组，若设置 false，则只返回该节点的值
}
const catIds = ref([])
const options = ref([])
const relationTableData = ref([])
const currentBrandId = ref(null) // 用于存储当前行的 brandId
/**
 * 关联分类·按钮
 */
const handleRelation = brandId => {
  relationDialogVisible.value = true
  //存储当前行的 brandId
  currentBrandId.value = brandId
  //获取关联分类列表
  getRelationList(brandId)
}

/**
 * 移除关联
 */
const deleteRelation = id => {
  ElMessageBox.confirm('你确定要删除吗?', 'Warning', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  })
    .then(async () => {
      //发送删除请求
      await removeRelation(id)
      //刷新数据
      getRelationList(currentBrandId.value)
    })
    .catch(() => {
      ElMessage({
        type: 'info',
        message: '取消删除'
      })
    })
}
/**
 * 新增关联分类按钮
 */
const cascaderSelect = async () => {
  //请求数据进行回显
  options.value = await categoryList()
  showCascaderSelect.value = true
}

/**
 * 穿梭框取消按钮
 */
const cancelTreeSelect = () => {
  showCascaderSelect.value = false
  //清空catIds数组
  catIds.value = []
}
/**
 * 确定按钮
 */
const confirmTreeSelect = () => {
  //获取选中的分类catIds数组
  //console.log(catIds.value)
  //收集选中的分类catIds数组和brandId,可以多选，所以是数组,转为一个对象数组
  const dataArray = catIds.value.map(item => ({ brandId: currentBrandId.value, catId: item }))
  // console.log(dataArray)
  batchSaveRelationArrayData(dataArray)
  //清空catIds数组
  catIds.value = []
  //关闭级联选择器
  showCascaderSelect.value = false
  //刷新下面级联表格中的数据
  getRelationList(currentBrandId.value)
}
/**
 * 获取表格数据
 * @param brandId
 */
const getRelationList = async brandId => {
  const { records, total } = await relationList(
    relationPageNo.value,
    relationPageSize.value,
    brandId
  )
  relationTableData.value = records
  relationTotalCount.value = total
}
/**
 * 批量添加
 * @param dataArry
 */
const batchSaveRelationArrayData = async dataArry => {
  await batchSaveRelation(dataArry)
}

const handleRelationSizeChange = () => {
  getRelationList(currentBrandId.value)
}

const handleRelationCurrentChange = () => {
  getRelationList(currentBrandId.value)
}
</script>

<style scoped>
.el-table .warning-row {
  --el-table-tr-bg-color: var(--el-color-warning-light-9);
}
.el-table .success-row {
  --el-table-tr-bg-color: var(--el-color-success-light-9);
}

.avatar-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
</style>
